package com.yyfax.infrastructure.upgrade;

import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore.MediaColumns;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

public class Assistant {
	public static boolean DEBUG = true;
	public static boolean LOGIN_TEST_SERVER = false;
	public static int LOGIN_WHICH_TEST_SERVER;

	@SuppressWarnings("UnusedDeclaration")
    public static int dp2pixel(Context ctx, int dp) {
		return (int) (5 * ctx.getResources().getDisplayMetrics().density + 0.5f);
	}

	@SuppressWarnings("UnusedDeclaration")
    public static String getIPAddress(boolean useIPv4) {
		try {
			List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
			for (NetworkInterface i : interfaces) {
				List<InetAddress> addressList = Collections.list(i.getInetAddresses());
				for (InetAddress address : addressList) {
					if (!address.isLoopbackAddress()) {
						String addressString = address.getHostAddress();
						boolean isIPv4 = isIPv4Address(addressString);
						if (useIPv4) {
							if (isIPv4)
								return addressString;
						} else {
							if (!isIPv4) {
								int delim = addressString.indexOf('%'); // drop ip6 port suffix
								return delim < 0 ? addressString : addressString.substring(0, delim);
							}
						}
					}
				}
			}
		} catch (Exception ignored) {
		} // for now eat exceptions
		return "";
	}

	private static final Pattern IPV4_PATTERN =
			Pattern.compile("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");

	private static boolean isIPv4Address(final String input) {
		return IPV4_PATTERN.matcher(input).matches();
	}

	public static String bytesToHexString(byte[] src) {
		return bytesToHexString(src, 0, src.length);
	}

	public static String bytesToHexString(byte[] src, int offset, int size) {
		StringBuilder sb = new StringBuilder("");
		if (src == null || src.length <= 0 || offset + size > src.length) {
			return null;
		}
		for (int i = offset; i < offset + size; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				sb.append(0);
			}
			sb.append(hv);
		}
		return sb.toString();
	}

	public static boolean isNetworkConnected(Context context) {
		final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo activeNetwork = connMgr.getActiveNetworkInfo();
		return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
	}

	public static boolean installApk(Context c, File f) {
		return installApk(c, Uri.fromFile(f));
	}

	public static String getFilePathFromContentUri(Context c, Uri selectedVideoUri) {
		String filePath;
		String[] filePathColumn = { MediaColumns.DATA };
		ContentResolver contentResolver = c.getContentResolver();
		Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null);
		cursor.moveToFirst();

		int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
		filePath = cursor.getString(columnIndex);
		cursor.close();
		return filePath;
	}

	@SuppressWarnings("UnusedDeclaration")
    public static String getFilePathFromUri(Context c, Uri uri) {
		String filePath = null;
		if ("content".equals(uri.getScheme())) {
			String[] filePathColumn = { MediaColumns.DATA };
			ContentResolver contentResolver = c.getContentResolver();
			Cursor cursor = contentResolver.query(uri, filePathColumn, null, null, null);
			cursor.moveToFirst();

			int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
			filePath = cursor.getString(columnIndex);
			cursor.close();
		} else if ("file".equals(uri.getScheme())) {
			filePath = new File(uri.getPath()).getAbsolutePath();
		}
		return filePath;
	}

	public static Uri getFileUri(Context c, Uri uri) {
		if ("content".equals(uri.getScheme())) {
			final String filePath = getFilePathFromContentUri(c, uri);
			uri = Uri.fromFile(new File(filePath));
			return uri;
		} else if ("file".equals(uri.getScheme())) {
			return uri;
		}
		return null;
	}

	@SuppressWarnings("StatementWithEmptyBody")
    public static boolean installApk(Context c, Uri uri) {
		if ("content".equals(uri.getScheme())) {
			final String filePath = getFilePathFromContentUri(c, uri);
			uri = Uri.fromFile(new File(filePath));
		} else if ("file".equals(uri.getScheme())) {
			// pass
		} else {
			return false;
		}

		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setDataAndType(uri, "application/vnd.android.package-archive");
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		c.startActivity(intent);
		return true;
	}

	public static String getVersionName(Context context) {
		PackageManager packageManager = context.getPackageManager();
		try {
			PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
			return packageInfo.versionName;
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	public static int getVersionCode(Context context) {
		PackageManager packageManager = context.getPackageManager();
		try {
			PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
			return packageInfo.versionCode;
		} catch (Exception e) {
			e.printStackTrace();
			return 1;
		}
	}

	public static void goHome(Context context) {
		Intent intent = new Intent(Intent.ACTION_MAIN);
		intent.addCategory(Intent.CATEGORY_HOME);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startActivity(intent);
	}

	/* Checks if external storage is available for read and write */
	public static boolean isExternalStorageWritable() {
		String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state);
    }

	public static void loadConfig(Context c) {
//		DEBUG = c.getResources().getBoolean(R.bool.config_DEBUG);
		DEBUG = true;
	}

    @SuppressWarnings("UnusedDeclaration")
    public static void copyRes(Context c, int resId, String path) throws IOException {
		FileOutputStream os = new FileOutputStream(path);
		copyRes(c, resId, os);
    }

    public static void copyRes(Context c, int resId, OutputStream os) throws IOException {
        InputStream in = c.getResources().openRawResource(resId);
        byte[] buff = new byte[1024];
        int read;
        try {
            while ((read = in.read(buff)) > 0) {
                os.write(buff, 0, read);
            }
        } finally {
            in.close();
            os.close();
        }
    }

	/**
	 * 并行执行异步任务
	 * @param task 目标任务实例
	 * @param params 执行参数
	 * @param <T>
	 */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static <T> void executeAsyncTaskParallel(AsyncTask<T, ?, ?> task, T... params) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
        } else {
            task.execute(params);
        }
    }
}
